
#include <math.h>

namespace HairEngine
{
	class Vector3D
	{
	public:
		float x;
		float y;
		float z;
	
	
		Vector3D()
		{
			x = 0.0f;
			y = 0.0f;
			z = 0.0f;
		}
	
		Vector3D(float x, float y, float z)
		{
			this->x = x;
			this->y = y;
			this->z = z;	
		}
	
		Vector3D& operator= (Vector3D v)			// operator= sets values of v to this Vector3D. example: v1 = v2 means that values of v2 are set onto v1
		{
			x = v.x;
			y = v.y;
			z = v.z;
			return *this;
		}

		Vector3D operator+ (Vector3D v)				// operator+ is used to add two Vector3D's. operator+ returns a new Vector3D
		{
			return Vector3D(x + v.x, y + v.y, z + v.z);
		}

		Vector3D operator- (Vector3D v)				// operator- is used to take difference of two Vector3D's. operator- returns a new Vector3D
		{
			return Vector3D(x - v.x, y - v.y, z - v.z);
		}

		Vector3D operator* (float value)			// operator* is used to scale a Vector3D by a value. This value multiplies the Vector3D's x, y and z.
		{
			return Vector3D(x * value, y * value, z * value);
		}

		Vector3D operator/ (float value)			// operator/ is used to scale a Vector3D by a value. This value divides the Vector3D's x, y and z.
		{
			return Vector3D(x / value, y / value, z / value);
		}

		Vector3D& operator+= (Vector3D v)			// operator+= is used to add another Vector3D to this Vector3D.
		{
			x += v.x;
			y += v.y;
			z += v.z;
			return *this;
		}

		Vector3D& operator-= (Vector3D v)			// operator-= is used to subtract another Vector3D from this Vector3D.
		{
			x -= v.x;
			y -= v.y;
			z -= v.z;
			return *this;
		}

		Vector3D& operator*= (float value)			// operator*= is used to scale this Vector3D by a value.
		{
			x *= value;
			y *= value;
			z *= value;
			return *this;
		}

		Vector3D& operator/= (float value)			// operator/= is used to scale this Vector3D by a value.
		{
			x /= value;
			y /= value;
			z /= value;
			return *this;
		}


		Vector3D operator- ()						// operator- is used to set this Vector3D's x, y, and z to the negative of them.
		{
			return Vector3D(-x, -y, -z);
		}

		float length()								// length() returns the length of this Vector3D
		{
			return sqrtf(x*x + y*y + z*z);
		};

		void unitize()								// unitize() normalizes this Vector3D that its direction remains the same but its length is 1.
		{
			float length = this->length();

			if (length == 0)
				return;

			x /= length;
			y /= length;
			z /= length;
		}

		Vector3D unit()								// unit() returns a new Vector3D. The returned value is a unitized version of this Vector3D.
		{
			float length = this->length();

			if (length == 0)
				return *this;
		
			return Vector3D(x / length, y / length, z / length);
		}
	};
}

